package com.micro;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Date;

public class test1 {

    @Test
    public void test() throws Exception{
//        创建excal表，并且写数据
//        三种表格式，HSSF,XSSF,SXSSF,最好选择SXSSF
//        优点：可以写非常大的数据量，如100万条甚至更多条写数据速度快，占用更少的内存
        /*
        * 过程中会产生临时文件，需要清理临时文件默认由100条记录被保存在内存中，
        * 如果超过这数量，则最前面的数据被写入临时文件如果想自定义内存中数据的数量，
        * 可以使用new SXSSFWorkbook（数量）
        * */
//        创建一个工作表对象
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
//        创建一个表对象
        Sheet sheet = sxssfWorkbook.createSheet("第一页");
//        创建行和单元格，并且写入数据
        for (int rowNum = 0;rowNum<100000;rowNum++){
            //3.创建行
            Row row = sheet.createRow(rowNum);
            for (int CellNum = 0;CellNum<10;CellNum++){
                Cell cell = row.createCell(CellNum);
                cell.setCellValue(CellNum);
            }
        }

        System.out.println("over");

        // 获取资源目录路径并创建文件输出流
        URL resourceUrl = getClass().getClassLoader().getResource("");
        String resourceFolderPath = Paths.get(resourceUrl.toURI()).toString();
        String filePath = resourceFolderPath+ File.separator+"test.xlsx";

        File file = new File(filePath);
        FileOutputStream fos = new FileOutputStream(file);

        //生成一张表
        sxssfWorkbook.write(fos);
        fos.close();
        //清除临时文件
        ((SXSSFWorkbook) sxssfWorkbook).dispose();
    }

    @Test
    public void CellType03() throws Exception{
        URL resourceUrl = getClass().getClassLoader().getResource("");
        String resourceFolderPath = Paths.get(resourceUrl.toURI()).toString();
        String filePath = resourceFolderPath+ File.separator+"test.xlsx";
        //获取文件流
        FileInputStream fis = new FileInputStream(new File(filePath));


        //获取一个工作簿
        Workbook workbook = new XSSFWorkbook(fis);
        //获取一个工作表
        Sheet sheet = workbook.getSheetAt(0);
        //获取第一行内容
        Row row = sheet.getRow(0);
        if (row != null){
            //获取所有的列
            int Cells = row.getPhysicalNumberOfCells();
            for (int col = 0;col < Cells;col++){
                //获取当前列
                Cell cell = row.getCell(col);
                if (cell != null){
                    //获取当前行的第 col 列的值
                    double cellValue = cell.getNumericCellValue();
                    System.out.print(cellValue+" | ");
                }
            }
        }
        //获取标准的内容
        //获取有多少行
        int rowCount = sheet.getPhysicalNumberOfRows();
        //从1开始，第一行是标题
        for (int rowNum = 1;rowNum < rowCount;rowNum++){
            Row rowData = sheet.getRow(rowNum);
            if (rowData != null){
                //获取当前行的列数
                int cellCount = rowData.getPhysicalNumberOfCells();
                System.out.println();
                for (int col = 0;col < cellCount;col++){
                    //获取当前列的值
                    Cell cellData = rowData.getCell(col);
                    //打印当前行当前列的值
                    System.out.print("["+(rowNum+1)+"-"+(col+1)+"]");
                    
                    //匹配列的类型
                    if (cellData != null){
                        //获取列的类型
                        int cellType = cellData.getCellType();
                        String cellValue = "";
                        switch (cellType){
                            case  Cell.CELL_TYPE_STRING://字符串
                                System.out.print("[string]");
                                cellValue = cellData.getStringCellValue();
                                break;
                            case  Cell.CELL_TYPE_BOOLEAN://布尔
                                System.out.print("[boolean]");
                                cellValue = String.valueOf(cellData.getBooleanCellValue());
                                break;
                            case  Cell.CELL_TYPE_BLANK://空
                                System.out.print("[blank]");
                                break;
                            case  Cell.CELL_TYPE_NUMERIC://数字（日期、普通数字）
                                System.out.print("[numeric]");
                                if (HSSFDateUtil.isCellDateFormatted(cellData)){
                                    //如果是日期
                                    System.out.print("[日期] ");
                                    Date date = cellData.getDateCellValue();
                                }else {
                                    //不是日期格式，防止数字过长
                                    System.out.print("[转换字符串输出] ");
                                    //转为字符串
                                    cellData.setCellType(HSSFCell.CELL_TYPE_STRING);
                                    cellValue = cellData.toString();

                                }
                                break;
                            case  Cell.CELL_TYPE_ERROR://错误
                                System.out.print("[error]");
                                break;
                        }
                        System.out.print("["+cellValue+"]\n");
                    }
                }
            }
        }

        System.out.println();
        System.out.println("over");
        fis.close();
    }

    @Test
    public void test3(){
        // 工作因子，默认值是10，最小值是4，最大值是31，值越大运算速度越慢
        PasswordEncoder encoder = new BCryptPasswordEncoder(4);
        //明文："password"
        //密文：result，即使明文密码相同，每次生成的密文也不一致
        String result = encoder.encode("password");
        System.out.println(result);

        //密码校验
        Assert.isTrue(encoder.matches("password", result), "密码不一致");
    }

}
